const path = require('path');
const { readdirSync } = require('fs');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const env = require('./env');

const baseRules = [
  {
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    options: {
      presets: [
        [
          '@babel/preset-env',
          {
            // 按需加载
            useBuiltIns: 'usage',
            //指定core-js 版本
            corejs: {
              version: 3
            },
            // 指定兼容性做到哪个版本
            targets: {
              chrome: '60',
              firefox: '60',
              ie: '9',
              safari: '10',
              edge: '17'
            }
          }
        ]
      ],
      ...(process.env.NODE_ENV === 'production' ? {} : { cacheDirectory: true })
    }
  },
  {
    test: /\.(jpe?g|png|gif)$/,
    type: 'asset',
    //解析
    parser: {
      //转base64的条件
      dataUrlCondition: {
        maxSize: 8 * 1024, // 8kb
      }
    },
    generator: {
      //与output.assetModuleFilename是相同的,这个写法引入的时候也会添加好这个路径
      filename: 'img/[name].[hash:6][ext]',
      //打包后对资源的引入，文件命名已经有/img了
      publicPath: './'
    },
  },
  {
    test: /\.html$/,
    /**处理html文件的img图片，从而能被url-loader 处理 */
    loader: 'html-loader'
  },
  {
    exclude: /\.(js|css|less|jpg|png|jpeg|gif|html)$/,
    type: 'asset',
    parser: {
      dataUrlCondition: {
        maxSize: 8 * 1024,
      }
    },
    generator: {
      filename: 'asstes/[name]_[hash:8].[ext]',
      publicPath: './'
    }
  }
]

const dllPath = path.resolve(__dirname, '../public/vendor');

function getDllRefrencePlugin() {
  const dir = readdirSync(dllPath);
  const manifestJson = [];
  const result = [];
  dir.map(file => {
    if (/.json$/.test(file)) {
      manifestJson.push(file);
    }
  })
  manifestJson.map(manifest => {
    result.push(new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, dllPath, manifest)
    }))
  })
  return result
}

module.exports = {
  entry: path.resolve(__dirname, '../src/index.js'),
  output: {
    filename: 'js/[name].[contenthash:10].js',
    path: path.resolve(__dirname, '../dist')
  },
  module: {
    rules: [
      {
        oneOf: baseRules
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html'),
      ...(process.env.NODE_ENV === 'production' ?
        {
          minify: {
            // 移除空格
            collapseWhitespace: true,
            // 移除注释
            removeComments: true
          }
        } :
        {}
      )
    }),
    new webpack.DefinePlugin({
      'process.env': {
        ...env,
        NODE_ENV: JSON.stringify(process.env.NODE_ENV)
      }
    }),
    /** 不需要打包进去的包的映射 */
    ...getDllRefrencePlugin(),
    new AddAssetHtmlWebpackPlugin({
      filepath: path.resolve(__dirname, dllPath, '*.dll.js'),
      outputPath: './vendor',
      publicPath: './vendor'
    }),
    new BundleAnalyzerPlugin()
  ],
  optimization: {
    splitChunks: {
      chunks: 'all'
    },
  },
};
